/**
 * @file farm_hash_test.h
 * @author Chase Geigle
 *
 * This file contains the test vectors for our farmhashna implementation.
 * These are ported directly from the MIT Licensed test code on the
 * google/farmhash repository.
 *
 * @see https://github.com/google/farmhash/blob/master/src/farmhash.cc#L4491-L5728
 */

#include "bandit/bandit.h"
#include "meta/hashing/hashes/farm_hash.h"

namespace
{

uint32_t create_seed(int offset, int salt)
{
    using namespace meta::hashing::farm;
    uint32_t h
        = static_cast<uint32_t>(static_cast<unsigned>(salt) & 0xffffffff);
    h = h * c1;
    h ^= (h >> 17);
    h = h * c1;
    h ^= (h >> 17);
    h = h * c1;
    h ^= (h >> 17);
    h += static_cast<uint32_t>(static_cast<unsigned>(offset) & 0xffffffff);
    h = h * c1;
    h ^= (h >> 17);
    h = h * c1;
    h ^= (h >> 17);
    h = h * c1;
    h ^= (h >> 17);
    return h;
}

uint32_t expected[] = {
    1140953930u, 861465670u,  3277735313u, 2681724312u, 2598464059u,
    797982799u,  890626835u,  800175912u,  2603993599u, 921001710u,
    1410420968u, 2134990486u, 3283896453u, 1867689945u, 2914424215u,
    2244477846u, 255297188u,  2992121793u, 1110588164u, 4186314283u,
    161451183u,  3943596029u, 4019337850u, 452431531u,  283198166u,
    2741341286u, 3379021470u, 2557197665u, 299850021u,  2532580744u,
    452473466u,  1706958772u, 1298374911u, 3099673830u, 2199864459u,
    3696623795u, 236935126u,  2976578695u, 4055299123u, 3281581178u,
    1053458494u, 1882212500u, 2305012065u, 2169731866u, 3456121707u,
    275903667u,  458884671u,  3033004529u, 3058973506u, 2379411653u,
    1898235244u, 1402319660u, 2700149065u, 2699376854u, 147814787u,
    720739346u,  2433714046u, 4222949502u, 4220361840u, 1712034059u,
    3425469811u, 3690733394u, 4148372108u, 1330324210u, 594028478u,
    2921867846u, 1635026870u, 192883107u,  780716741u,  1728752234u,
    3280331829u, 326029180u,  3969463346u, 1436364519u, 393215742u,
    3349570000u, 3824583307u, 1612122221u, 2859809759u, 3808705738u,
    1379537552u, 1646032583u, 2233466664u, 1432476832u, 4023053163u,
    2650381482u, 2052294713u, 3552092450u, 1628777059u, 1499109081u,
    3476440786u, 3829307897u, 2960536756u, 1554038301u, 1145519619u,
    3190844552u, 2902102606u, 3600725550u, 237495366u,  540224401u,
    65721842u,   489963606u,  1448662590u, 397635823u,  1596489240u,
    1562872448u, 1790705123u, 2128624475u, 180854224u,  2604346966u,
    1435705557u, 1262831810u, 155445229u,  1672724608u, 1669465176u,
    1341975128u, 663607706u,  2077310004u, 3610042449u, 1911523866u,
    1043692997u, 1454396064u, 2563776023u, 294527927u,  1099072299u,
    1389770549u, 703505868u,  678706990u,  2952353448u, 2026137563u,
    3603803785u, 629449419u,  1933894405u, 3043213226u, 226132789u,
    2489287368u, 1552847036u, 645684964u,  3828089804u, 3632594520u,
    187883449u,  230403464u,  3151491850u, 3272648435u, 3729087873u,
    1303930448u, 2002861219u, 165370827u,  916494250u,  1230085527u,
    3103338579u, 3064290191u, 3807265751u, 3628174014u, 231181488u,
    851743255u,  2295806711u, 1781190011u, 2988893883u, 1554380634u,
    1142264800u, 3667013118u, 1968445277u, 315203929u,  2638023604u,
    2290487377u, 732137533u,  1909203251u, 440398219u,  1891630171u,
    1380301172u, 1498556724u, 4072067757u, 4165088768u, 4204318635u,
    441430649u,  3931792696u, 197618179u,  956300927u,  914413116u,
    3010839769u, 2837339569u, 2148126371u, 1913303225u, 3074915312u,
    3117299654u, 4139181436u, 2993479124u, 3178848746u, 1357272220u,
    1438494951u, 507436733u,  667183474u,  2084369203u, 3854939912u,
    1413396341u, 126024219u,  146044391u,  1016656857u, 3022024459u,
    3254014218u, 429095991u,  165589978u,  1578546616u, 985653208u,
    1718653828u, 623071693u,  366414107u,  249776086u,  1207522198u,
    3047342438u, 2991127487u, 3120876698u, 1684583131u, 46987739u,
    1157614300u, 863214540u,  1087193030u, 199124911u,  520792961u,
    3614377032u, 586863115u,  3331828431u, 1013201099u, 1716848157u,
    4033596884u, 1164298657u, 4140791139u, 1146169032u, 1434258493u,
    3824360466u, 3242407770u, 3725511003u, 232064808u,  872586426u,
    762243036u,  2736953692u, 816692935u,  512845449u,  3748861010u,
    2266795890u, 3781899767u, 4290630595u, 517646945u,  22638523u,
    648000590u,  959214578u,  558910384u,  1283799121u, 3047062993u,
    1024246061u, 4027776454u, 3544509313u, 622325861u,  834785312u,
    382936554u,  411505255u,  1973395102u, 1825135056u, 2725923798u,
    580988377u,  2826990641u, 3474970689u, 1029055034u, 812546227u,
    2506885666u, 2584372201u, 1758123094u, 589567754u,  325737734u,
    345313518u,  2022370576u, 3886113119u, 3338548567u, 257578986u,
    3698087965u, 1776047957u, 1771384107u, 3604937815u, 3198590202u,
    2305332220u, 191910725u,  4232136669u, 427759438u,  4244322689u,
    542201663u,  3315355162u, 2135941665u, 556609672u,  45845311u,
    1175961330u, 3948351189u, 23075771u,   3252374102u, 1634635545u,
    4151937410u, 713127376u,  1467786451u, 663013031u,  3444053918u,
    2638154051u, 810082938u,  3077742128u, 1062268187u, 2115441882u,
    4081398201u, 3735739145u, 2794294783u, 2335576331u, 2560479831u,
    1379288194u, 4225182569u, 2442302747u, 3948961926u, 3958366652u,
    3067277639u, 3667516477u, 1709989541u, 1516711748u, 2339636583u,
    4188504038u, 59581167u,   2725013602u, 3639843023u, 2658147000u,
    2643979752u, 3758739543u, 4189944477u, 2470483982u, 877580602u,
    2995362413u, 118817200u,  3252925478u, 2062343506u, 3981838403u,
    3762572073u, 1231633714u, 4168280671u, 2931588131u, 3284356565u,
    1129162571u, 732225574u,  4173605289u, 1407328702u, 1677744031u,
    3532596884u, 3232041815u, 1652884780u, 2256541290u, 3459463480u,
    3740979556u, 259034107u,  2227121257u, 1426140634u, 3606709555u,
    3424793077u, 315836068u,  3200749877u, 1386256573u, 24035717u,
    2982018998u, 1811050648u, 234531934u,  1115203611u, 1598686658u,
    3146815575u, 1603559457u, 323296368u,  2632963283u, 1778459926u,
    739944537u,  579625482u,  3486330348u, 492621815u,  1231665285u,
    2457048126u, 3903349120u, 389846205u,  3355404249u, 3275550588u,
    1052645068u, 862072556u,  2834153464u, 1481069623u, 2657392572u,
    4279236653u, 1688445808u, 701920051u,  3740748788u, 3388062747u,
    1873358321u, 2152785640u, 883382081u,  1005815394u, 1020177209u,
    734239551u,  2371453141u, 100326520u,  3488500412u, 1279682138u,
    2610427744u, 49703572u,   3026361211u, 605900428u,  302392721u,
    2509302188u, 1416453607u, 2815915291u, 1862819968u, 519710058u,
    2450888314u, 4017598378u, 937074653u,  3035635454u, 1590230729u,
    3268013438u, 2710029305u, 12886044u,   3711259084u, 2627383582u,
    3895772404u, 648534979u,  260307902u,  855990313u,  3669691805u,
    263366740u,  2938543471u, 414331688u,  3080542944u, 3405007814u,
    3565059103u, 1190977418u, 390836981u,  1606450012u, 2649808239u,
    2514169310u, 2747519432u, 4129538640u, 1721522849u, 492099164u,
    792990594u,  3625507637u, 2271095827u, 2993032712u, 2302363854u,
    4013112951u, 1111617969u, 2183845740u, 795918276u,  1116991810u,
    3110898804u, 3963062126u, 2737064702u, 462795667u,  937372240u,
    1343017609u, 1091041189u, 2790555455u, 277024217u,  25485284u,
    1166522068u, 1623631848u, 241727183u,  2836158787u, 3112996740u,
    573836428u,  2721658101u, 1937681565u, 4175169209u, 3190765433u,
    1970000788u, 1668258120u, 114616703u,  954762543u,  199237753u,
    4094644498u, 2522281978u, 732086117u,  1756889687u, 2936126607u,
    2437031370u, 4103143808u, 3883389541u, 3171090854u, 2483004780u,
    1927385370u, 2360538162u, 2740855009u, 4241185118u, 1492209542u,
    1672737098u, 2148675559u, 1789864670u, 2434313103u, 2319172611u,
    2760941207u, 2636210123u, 1338083267u, 1128080590u, 822806371u,
    1199583556u, 314727461u,  1335160250u, 2084630531u, 1156261526u,
    316766066u,  112090465u,  3129033323u, 2746885618u, 636616055u,
    2582210744u, 1721064910u, 3468394263u, 470463518u,  2076016059u,
    408721884u,  2121041886u, 378460278u,  1915948002u, 357324860u,
    2301682622u, 2691859523u, 1869756364u, 2429314418u, 2193146527u,
    1185564327u, 2614088922u, 1975527044u, 919067651u,  2855948894u,
    3662539576u, 1943802836u, 3529473373u, 1490330107u, 366036094u,
    3384241033u, 4276268604u, 448403661u,  4271796078u, 1910401882u,
    3077107698u, 299427366u,  2035665349u, 3201262636u, 3738454258u,
    2554452696u, 3588997135u, 3363895827u, 1267505995u, 1852004679u,
    2237827073u, 2803250686u, 3468044908u, 2143572850u, 1728158656u,
    1022551180u, 1996680960u, 839529273u,  2400647871u, 2201096054u,
    3606433628u, 2597259793u, 3544595875u, 3909443124u, 819278607u,
    3447346709u, 806136613u,  2711436388u, 3656063205u, 837475154u,
    694525336u,  4070212073u, 4011303412u, 1068395209u, 438095290u,
    484603494u,  2673730227u, 737767009u,  642310823u,  3914002299u,
    308425103u,  268427550u,  1334387085u, 4069797497u, 4280783219u,
    2914011058u, 4243643405u, 2849988118u, 2504230175u, 1817156623u,
    2804200483u, 3406991497u, 2948254999u, 2102063419u, 1071272117u,
    514889942u,  571972433u,  1246595599u, 1735616066u, 1539151988u,
    1230831543u, 277987182u,  4269526481u, 991511607u,  95237878u,
    2005032160u, 1291113144u, 626619670u,  3560835907u, 164940926u,
    1433635018u, 116647396u,  3039097112u, 2868163232u, 1141645918u,
    1764165478u, 881378302u,  2159170082u, 2953647681u, 1011320066u,
    184856151u,  1723308975u, 336034862u,  2017579106u, 1476681709u,
    147523618u,  3896252223u, 2264728166u, 944743644u,  1694443528u,
    2690700128u, 1947321519u, 735478508u,  4058183171u, 260177668u,
    505662155u,  2391691262u, 1920739747u, 3216960415u, 1898176786u,
    3722741628u, 1511077569u, 449636564u,  983350414u,  2580237367u,
    2055059789u, 1103819072u, 2089123665u, 3873755579u, 2718467458u,
    3124338704u, 3204250304u, 2475035432u, 1120017626u, 3873758287u,
    1982999824u, 2950794582u, 780634378u,  2842141483u, 4029205195u,
    1656892865u, 3330993377u, 80890710u,   1953796601u, 3873078673u,
    136118734u,  2317676604u, 4199091610u, 1864448181u, 3063437608u,
    1699452298u, 1403506686u, 1513069466u, 2348491299u, 4273657745u,
    4055855649u, 1805475756u, 2562064338u, 973124563u,  4197091358u,
    172861513u,  2858726767u, 4271866024u, 3071338162u, 3590386266u,
    2328277259u, 1096050703u, 1189614342u, 459509140u,  771592405u,
    817999971u,  3740825152u, 520400189u,  1941874618u, 185232757u,
    4032960199u, 3928245258u, 3527721294u, 1301118856u, 752188080u,
    3512945009u, 308584855u,  2105373972u, 752872278u,  3823368815u,
    3760952096u, 4250142168u, 2565680167u, 3646354146u, 1259957455u,
    1085857127u, 3471066607u, 38924274u,   3770488806u, 1083869477u,
    3312508103u, 71956383u,   3738784936u, 3099963860u, 1255084262u,
    4286969992u, 3621849251u, 1190908967u, 1831557743u, 2363435042u,
    54945052u,   4059585566u, 4023974274u, 1788578453u, 3442180039u,
    2534883189u, 2432427547u, 3909757989u, 731996369u,  4168347425u,
    1356028512u, 2741583197u, 1280920000u, 312887059u,  3259015297u,
    3946278527u, 4135481831u, 1281043691u, 1121403845u, 3312292477u,
    1819941269u, 1741932545u, 3293015483u, 2127558730u, 713121337u,
    2635469238u, 486003418u,  4015067527u, 2976737859u, 2108187161u,
    927011680u,  1970188338u, 4177613234u, 1799789551u, 2118505126u,
    4134691985u, 1958963937u, 1929210029u, 2555835851u, 2768832862u,
    910892050u,  2567532373u, 4075249328u, 86689814u,   3726640307u,
    1392137718u, 1240000030u, 4104757832u, 3026358429u, 313797689u,
    1435798509u, 3101500919u, 1241665335u, 3573008472u, 3615577014u,
    3767659003u, 3134294021u, 4063565523u, 2296824134u, 1541946015u,
    3087190425u, 2693152531u, 2199672572u, 2123763822u, 1034244398u,
    857839960u,  2515339233u, 2228007483u, 1628096047u, 2116502287u,
    2502657424u, 2809830736u, 460237542u,  450205998u,  3646921704u,
    3818199357u, 1808504491u, 1950698961u, 2069753399u, 3657033172u,
    3734547671u, 4067859590u, 3292597295u, 1106466069u, 356742959u,
    2469567432u, 3495418823u, 183440071u,  3248055817u, 3662626864u,
    1750561299u, 3926138664u, 4088592524u, 567122118u,  3810297651u,
    992181339u,  3384018814u, 3272124369u, 3177596743u, 320086295u,
    2316548367u, 100741310u,  451656820u,  4086604273u, 3759628395u,
    2553391092u, 1745659881u, 3650357479u, 2390172694u, 330172533u,
    767377322u,  526742034u,  4102497288u, 2088767754u, 164402616u,
    2482632320u, 2352347393u, 1873658044u, 3861555476u, 2751052984u,
    1767810825u, 20037241u,   545143220u,  2594532522u, 472304191u,
    3441135892u, 3323383489u, 258785117u,  2977745165u, 2781737565u,
    2963590112u, 2756998822u, 207428029u,  2581558559u, 3824717027u,
    1258619503u, 3472047571u, 2648427775u, 2360400900u, 2393763818u,
    2332399088u, 3932701729u, 884421165u,  1396468647u, 1377764574u,
    4061795938u, 1559119087u, 3343596838u, 3604258095u, 1435134775u,
    1099809675u, 908163739u,  1418405656u, 368446627u,  3741651161u,
    3374512975u, 3542220540u, 3244772570u, 200009340u,  3198975081u,
    2521038253u, 4081637863u, 337070226u,  3235259030u, 3897262827u,
    736956644u,  641040550u,  644850146u,  1306761320u, 4219448634u,
    193750500u,  3293278106u, 1383997679u, 1242645122u, 4109252858u,
    450747727u,  3716617561u, 362725793u,  2252520167u, 3377483696u,
    1788337208u, 8130777u,    3226734120u, 759239140u,  1012411364u,
    1658628529u, 2911512007u, 1002580201u, 1681898320u, 3039016929u,
    4294520281u, 367022558u,  3071359622u, 3205848570u, 152989999u,
    3839042136u, 2357687350u, 4273132307u, 3898950547u, 1176841812u,
    1314157485u, 75443951u,   1027027239u, 1858986613u, 2040551642u,
    36574105u,   2603059541u, 3456147251u, 2137668425u, 4077477194u,
    3565689036u, 491832241u,  363703593u,  2579177168u, 3589545214u,
    265993036u,  1864569342u, 4149035573u, 3189253455u, 1072259310u,
    3153745937u, 923017956u,  490608221u,  855846773u,  845706553u,
    1018226240u, 1604548872u, 3833372385u, 3287246572u, 2757959551u,
    2452872151u, 1553870564u, 1713154780u, 2649450292u, 500120236u,
    84251717u,   661869670u,  1444911517u, 2489716881u, 2810524030u,
    1561519055u, 3884088359u, 2509890699u, 4247155916u, 1005636939u,
    3224066062u, 2774151984u, 2035978240u, 2514910366u, 1478837908u,
    3144450144u, 2107011431u, 96459446u,   3587732908u, 2389230590u,
    3287635953u, 250533792u,  1235983679u, 4237425634u, 3704645833u,
    3882376657u, 2976369049u, 1187061987u, 276949224u,  4100839753u,
    1698347543u, 1629662314u, 1556151829u, 3784939568u, 427484362u,
    4246879223u, 3155311770u, 4285163791u, 1693376813u, 124492786u,
    1858777639u, 3476334357u, 1941442701u, 1121980173u, 3485932087u,
    820852908u,  358032121u,  2511026735u, 1873607283u, 2556067450u,
    2248275536u, 1528632094u, 1535473864u, 556796152u,  1499201704u,
    1472623890u, 1526518503u, 3692729434u, 1476438092u, 2913077464u,
    335109599u,  2167614601u, 4121131078u, 3158127917u, 3051522276u,
    4046477658u, 2857717851u, 1863977403u, 1341023343u, 692059110u,
    1802040304u, 990407433u,  3285847572u, 319814144u,  561105582u,
    1540183799u, 4052924496u, 2926590471u, 2244539806u, 439121871u,
    3317903224u, 3178387550u, 4265214507u, 82077489u,   1978918971u,
    4279668976u, 128732476u,  2853224222u, 464407878u,  4190838199u,
    997819001u,  3250520802u, 2330081301u, 4095846095u, 733509243u,
    1583801700u, 722314527u,  3552883023u, 1403784280u, 432327540u,
    1877837196u, 3912423882u, 505219998u,  696031431u,  908238873u,
    4189387259u, 8759461u,    2540185277u, 3385159748u, 381355877u,
    2519951681u, 1679786240u, 2019419351u, 4051584612u, 1933923923u,
    3768201861u, 1670133081u, 3454981037u, 700836153u,  1675560450u,
    371560700u,  338262316u,  847351840u,  2222395828u, 3130433948u,
    405251683u,  3037574880u, 184098830u,  453340528u,  1385561439u,
    2224044848u, 4071581802u, 1431235296u, 5570097u,    570114376u,
    2287305551u, 2272418128u, 803575837u,  3943113491u, 414959787u,
    708083137u,  2452657767u, 4019147902u, 3841480082u, 3791794715u,
    2965956183u, 2763690963u, 2350937598u, 3424361375u, 779434428u,
    1274947212u, 686105485u,  3426668051u, 3692865672u, 3057021940u,
    2285701422u, 349809124u,  1379278508u, 3623750518u, 215970497u,
    1783152480u, 823305654u,  216118434u,  1787189830u, 3692048450u,
    2272612521u, 3032187389u, 4159715581u, 1388133148u, 1611772864u,
    2544383526u, 552925303u,  3420960112u, 3198900547u, 3503230228u,
    2603352423u, 2318375898u, 4064071435u, 3006227299u, 4194096960u,
    1283392422u, 1510460996u, 174272138u,  3671038966u, 1775955687u,
    1719108984u, 1763892006u, 1385029063u, 4083790740u, 406757708u,
    684087286u,  531310503u,  3329923157u, 3492083607u, 1059031410u,
    3037314475u, 3105682208u, 3382290593u, 2292208503u, 426380557u,
    97373678u,   3842309471u, 777173623u,  3241407531u, 303065016u,
    1477104583u, 4234905200u, 2512514774u, 2649684057u, 1397502982u,
    1802596032u, 3973022223u, 2543566442u, 3139578968u, 3193669211u,
    811750340u,  4013496209u, 567361887u,  4169410406u, 3622282782u,
    3403136990u, 2540585554u, 895210040u,  3862229802u, 1145435213u,
    4146963980u, 784952939u,  943914610u,  573034522u,  464420660u,
    2356867109u, 3054347639u, 3985088434u, 1911188923u, 583391304u,
    176468511u,  2990150068u, 2338031599u, 519948041u,  3181425568u,
    496106033u,  4110294665u, 2736756930u, 1196757691u, 1089679033u,
    240953857u,  3399092928u, 4040779538u, 2843673626u, 240495962u,
    3017658263u, 3828377737u, 4243717901u, 2448373688u, 2759616657u,
    2246245780u, 308018483u,  4262383425u, 2731780771u, 328023017u,
    2884443148u, 841480070u,  3188015819u, 4051263539u, 2298178908u,
    2944209234u, 1372958390u, 4164532914u, 4074952232u, 1683612329u,
    2155036654u, 1872815858u, 2041174279u, 2368092311u, 206775997u,
    2283918569u, 645945606u,  115406202u,  4206471368u, 3923500892u,
    2217060665u, 350160869u,  706531239u,  2824302286u, 509981657u,
    1469342315u, 140980u,     1891558063u, 164887091u,  3094962711u,
    3437115622u, 13327420u,   422986366u,  330624974u,  3630863408u,
    2425505046u, 824008515u,  3543885677u, 918718096u,  376390582u,
    3224043675u, 3724791476u, 1837192976u, 2968738516u, 3424344721u,
    3187805406u, 1550978788u, 1743089918u, 4251270061u, 645016762u,
    3855037968u, 1928519266u, 1373803416u, 2289007286u, 1889218686u,
    1610271373u, 3059200728u, 2108753646u, 582042641u,  812347242u,
    3188172418u, 191994904u,  1343511943u, 2247006571u, 463291708u,
    2697254095u, 1534175504u, 1106275740u, 622521957u,  917121602u,
    4095777215u, 3955972648u, 3852234638u, 2845309942u, 3299763344u,
    2864033668u, 2554947496u, 799569078u,  2551629074u, 1102873346u,
    2661022773u, 2006922227u, 2900438444u, 1448194126u, 1321567432u,
    1983773590u, 1237256330u, 3449066284u, 1691553115u, 3274671549u,
    4271625619u, 2741371614u, 3285899651u, 786322314u,  1586632825u,
    564385522u,  2530557509u, 2974240289u, 1244759631u, 3263135197u,
    3592389776u, 3570296884u, 2749873561u, 521432811u,  987586766u,
    3206261120u, 1327840078u, 4078716491u, 1753812954u, 976892272u,
    1827135136u, 1781944746u, 1328622957u, 1015377974u, 3439601008u,
    2209584557u, 2482286699u, 1109175923u, 874877499u,  2036083451u,
    483570344u,  1091877599u, 4190721328u, 1129462471u, 640035849u,
    1867372700u, 920761165u,  3273688770u, 1623777358u, 3389003793u,
    3241132743u, 2734783008u, 696674661u,  2502161880u, 1646071378u,
    1164309901u, 350411888u,  1978005963u, 2253937037u, 7371540u,
    989577914u,  3626554867u, 3214796883u, 531343826u,  398899695u,
    1145247203u, 1516846461u, 3656006011u, 529303412u,  3318455811u,
    3062828129u, 1696355359u, 3698796465u, 3155218919u, 1457595996u,
    3191404246u, 1395609912u, 2917345728u, 1237411891u, 1854985978u,
    1091884675u, 3504488111u, 3109924189u, 1628881950u, 3939149151u,
    878608872u,  778235395u,  1052990614u, 903730231u,  2069566979u,
    2437686324u, 3163786257u, 2257884264u, 2123173186u, 939764916u,
    2933010098u, 1235300371u, 1256485167u, 1950274665u, 2180372319u,
    2648400302u, 122035049u,  1883344352u, 2083771672u, 3712110541u,
    321199441u,  1896357377u, 508560958u,  3066325351u, 2770847216u,
    3177982504u, 296902736u,  1486926688u, 456842861u,  601221482u,
    3992583643u, 2794121515u, 1533934172u, 1706465470u, 4281971893u,
    2557027816u, 900741486u,  227175484u,  550595824u,  690918144u,
    2825943628u, 90375300u,   300318232u,  1985329734u, 1440763373u,
    3670603707u, 2533900859u, 3253901179u, 542270815u,  3677388841u,
    307706478u,  2570910669u, 3320103693u, 1273768482u, 1216399252u,
    1652924805u, 1043647584u, 1120323676u, 639941430u,  325675502u,
    3652676161u, 4241680335u, 1545838362u, 1991398008u, 4100211814u,
    1097584090u, 3262252593u, 2254324292u, 1765019121u, 4060211241u,
    2315856188u, 3704419305u, 411263051u,  238929055u,  3540688404u,
    3094544537u, 3250435765u, 3460621305u, 1967599860u, 2016157366u,
    847389916u,  1659615591u, 4020453639u, 901109753u,  2682611693u,
    1661364280u, 177155177u,  3210561911u, 3802058181u, 797089608u,
    3286110054u, 2110358240u, 1353279028u, 2479975820u, 471725410u,
    2219863904u, 3623364733u, 3167128228u, 1052188336u, 3656587111u,
    721788662u,  3061255808u, 1615375832u, 924941453u,  2547780700u,
    3328169224u, 1310964134u, 2701956286u, 4145497671u, 1421461094u,
    1221397398u, 1589183618u, 1492533854u, 449740816u,  2686506989u,
    3035198924u, 1682886232u, 2529760244u, 3342031659u, 1235084019u,
    2151665147u, 2315686577u, 3282027660u, 1140138691u, 2754346599u,
    2091754612u, 1178454681u, 4226896579u, 2942520471u, 2122168506u,
    3751680858u, 3213794286u, 2601416506u, 4142747914u, 3951404257u,
    4243249649u, 748595836u,  4004834921u, 238887261u,  1927321047u,
    2217148444u, 205977665u,  1885975275u, 186020771u,  2367569534u,
    2941662631u, 2608559272u, 3342096731u, 741809437u,  1962659444u,
    3539886328u, 3036596491u, 2282550094u, 2366462727u, 2748286642u,
    2144472852u, 1390394371u, 1257385924u, 2205425874u, 2119055686u,
    46865323u,   3597555910u, 3188438773u, 2372320753u, 3641116924u,
    3116286108u, 2680722658u, 3371014971u, 2058751609u, 2966943726u,
    2345078707u, 2330535244u, 4013841927u, 1169588594u, 857915866u,
    1875260989u, 3175831309u, 3193475664u, 1955181430u, 923161569u,
    4068653043u, 776445899u,  954196929u,  61509556u,   4248237857u,
    3808667664u, 581227317u,  2893240187u, 4159497403u, 4212264930u,
    3973886195u, 2077539039u, 851579036u,  2957587591u, 772351886u,
    1173659554u, 946748363u,  2794103714u, 2094375930u, 4234750213u,
    3671645488u, 2614250782u, 2620465358u, 3122317317u, 2365436865u,
    3393973390u, 523513960u,  3645735309u, 2766686992u, 2023960931u,
    2312244996u, 1875932218u, 3253711056u, 3622416881u, 3274929205u,
    612094988u,  1555465129u, 2114270406u, 3553762793u, 1832633644u,
    1087551556u, 3306195841u, 1702313921u, 3675066046u, 1735998785u,
    1690923980u, 1482649756u, 1171351291u, 2043136409u, 1962596992u,
    461214626u,  3278253346u, 1392428048u, 3744621107u, 1028502697u,
    3991171462u, 1014064003u, 3642345425u, 3186995039u, 6114625u,
    3359104346u, 414856965u,  2814387514u, 3583605071u, 2497896367u,
    1024572712u, 1927582962u, 2892797583u, 845302635u,  328548052u,
    1523379748u, 3392622118u, 1347167673u, 1012316581u, 37767602u,
    2647726017u, 1070326065u, 2075035198u, 4202817168u, 2502924707u,
    2612406822u, 2187115553u, 1180137213u, 701024148u,  1481965992u,
    3223787553u, 2083541843u, 203230202u,  3876887380u, 1334816273u,
    2870251538u, 2186205850u, 3985213979u, 333533378u,  806507642u,
    1010064531u, 713520765u,  3084131515u, 2637421459u, 1703168933u,
    1517562266u, 4089081247u, 3231042924u, 3079916123u, 3154574447u,
    2253948262u, 1725190035u, 2452539325u, 1343734533u, 213706059u,
    2519409656u, 108055211u,  2916327746u, 587001593u,  1917607088u,
    4202913084u, 926304016u,  469255411u,  4042080256u, 3498936874u,
    246692543u,  495780578u,  438717281u,  2259272650u, 4011324645u,
    2836854664u, 2317249321u, 946828752u,  1280403658u, 1905648354u,
    2034241661u, 774652981u,  1285694082u, 2200307766u, 2158671727u,
    1135162148u, 232040752u,  397012087u,  1717527689u, 1720414106u,
    918797022u,  2580119304u, 3568069742u, 2904461070u, 3893453420u,
    973817938u,  667499332u,  3785870412u, 2088861715u, 1565179401u,
    600903026u,  591806775u,  3512242245u, 997964515u,  2339605347u,
    1134342772u, 3234226304u, 4084179455u, 302315791u,  2445626811u,
    2590372496u, 345572299u,  2274770442u, 3600587867u, 3706939009u,
    1430507980u, 2656330434u, 1079209397u, 2122849632u, 1423705223u,
    3826321888u, 3683385276u, 1057038163u, 1242840526u, 3987000643u,
    2398253089u, 1538190921u, 1295898647u, 3570196893u, 3065138774u,
    3111336863u, 2524949549u, 4203895425u, 3025864372u, 968800353u,
    1023721001u, 3763083325u, 526350786u,  635552097u,  2308118370u,
    2166472723u, 2196937373u, 2643841788u, 3040011470u, 4010301879u,
    2782379560u, 3474682856u, 4201389782u, 4223278891u, 1457302296u,
    2251842132u, 1090062008u, 3188219189u, 292733931u,  1424229089u,
    1590782640u, 1365212370u, 3975957073u, 3982969588u, 2927147928u,
    1048291071u, 2766680094u, 884908196u,  35237839u,   2221180633u,
    2490333812u, 4098360768u, 4029081103u, 3490831871u, 2392516272u,
    3455379186u, 3948800722u, 335456628u,  2105117968u, 4181629008u,
    1044201772u, 3335754111u, 540133451u,  3313113759u, 3786107905u,
    2627207327u, 3540337875u, 3473113388u, 3430536378u, 2514123129u,
    2124531276u, 3872633376u, 3272957388u, 3501994650u, 2418881542u,
    487365389u,  3877672368u, 1512866656u, 3486531087u, 2102955203u,
    1136054817u, 3004241477u, 1549075351u, 1302002008u, 3936430045u,
    2258587644u, 4109233936u, 3679809321u, 3467083076u, 2484463221u,
    1594979755u, 529218470u,  3527024461u, 1147434678u, 106799023u,
    1823161970u, 1704656738u, 1675883700u, 3308746763u, 1875093248u,
    1352868568u, 1898561846u, 2508994984u, 3177750780u, 4217929592u,
    400784472u,  80090315u,   3564414786u, 3841585648u, 3379293868u,
    160353261u,  2413172925u, 2378499279u, 673436726u,  1505702418u,
    1330977363u, 1853298225u, 3201741245u, 2135714208u, 4069554166u,
    3715612384u, 3692488887u, 3680311316u, 4274382900u, 914186796u,
    2264886523u, 3869634032u, 1254199592u, 1131020455u, 194781179u,
    429923922u,  2763792336u, 2052895198u, 3997373194u, 3440090658u,
    2165746386u, 1575500242u, 3463310191u, 2064974716u, 3779513671u,
    3106421434u, 880320527u,  3281914119u, 286569042u,  3909096631u,
    122359727u,  1429837716u, 252230074u,  4111461225u, 762273136u,
    93658514u,   2766407143u, 3623657004u, 3869801679u, 3925695921u,
    2390397316u, 2499025338u, 2741806539u, 2507199021u, 1659221866u,
    361292116u,  4048761557u, 3797133396u, 1517903247u, 3121647246u,
    3884308578u, 1697201500u, 1558800262u, 4150812360u, 3161302278u,
    2610217849u, 641564641u,  183814518u,  2075245419u, 611996508u,
    2223461433u, 329123979u,  121860586u,  860985829u,  1137889144u,
    4018949439u, 2904348960u, 947795261u,  1992594155u, 4255427501u,
    2281583851u, 2892637604u, 1478186924u, 3050771207u, 2767035539u,
    373510582u,  1963520320u, 3763848370u, 3756817798u, 627269409u,
    1806905031u, 1814444610u, 3646665053u, 1822693920u, 278515794u,
    584050483u,  4142579188u, 2149745808u, 3193071606u, 1179706341u,
    2693495182u, 3259749808u, 644172091u,  880509048u,  3340630542u,
    3365160815u, 2384445068u, 3053081915u, 2840648309u, 1986990122u,
    1084703471u, 2370410550u, 1627743573u, 2244943480u, 4057483496u,
    2611595995u, 2470013639u, 4024732359u, 3987190386u, 873421687u,
    2447660175u, 3226583022u, 767655877u,  2528024413u, 1962070688u,
    1233635843u, 2163464207u, 659054446u,  854207134u,  258410943u,
    4197831420u, 2515400215u, 3100476924u, 1961549594u, 2219491151u,
    3997658851u, 163850514u,  470325051u,  2598261204u, 3052145580u,
    59836528u,   1376188597u, 966733415u,  850667549u,  3622479237u,
    1083731990u, 1525777459u, 4005126532u, 1428155540u, 2781907007u,
    943739431u,  1493961005u, 2839096988u, 2000057832u, 1941829603u,
    1901484772u, 939810041u,  3377407371u, 3090115837u, 3310840540u,
    2068409688u, 3261383939u, 2212130277u, 2594774045u, 2912652418u,
    4179816101u, 3534504531u, 3349254805u, 2796552902u, 1385421283u,
    4259908631u, 3714780837u, 3070073945u, 3372846298u, 3835884044u,
    3047965714u, 3009018735u, 744091167u,  1861124263u, 2764936304u,
    1338171648u, 4222019554u, 1395200692u, 1371426007u, 3338031581u,
    2525665319u, 4196233786u, 2332743921u, 1474702008u, 2274266301u,
    4255175517u, 2290169528u, 1793910997u, 2188254024u, 354202001u,
    3864458796u, 4280290498u, 1554419340u, 1733094688u, 2010552302u,
    1561807039u, 664313606u,  2548990879u, 1084699349u, 3233936866u,
    973895284u,  2386881969u, 1831995860u, 2961465052u, 1428704144u,
    3269904970u, 231648253u,  2602483763u, 4125013173u, 3319187387u,
    3347011944u, 1892898231u, 4019114049u, 868879116u,  4085937045u,
    2378411019u, 1072588531u, 3547435717u, 2208070766u, 1069899078u,
    3142980597u, 2337088907u, 1593338562u, 919414554u,  688077849u,
    3625708135u, 1472447348u, 1947711896u, 3953006207u, 877438080u,
    845995820u,  3150361443u, 3053496713u, 2484577841u, 224271045u,
    2914958001u, 2682612949u, 806655563u,  2436224507u, 1907729235u,
    2920583824u, 1251814062u, 2070814520u, 4034325578u, 497847539u,
    2714317144u, 385182008u,  640855184u,  1327075087u, 1062468773u,
    1757405994u, 1374270191u, 4263183176u, 3041193150u, 1037871524u,
    3633173991u, 4231821821u, 2830131945u, 3505072908u, 2830570613u,
    4195208715u, 575398021u,  3992840257u, 3691788221u, 1949847968u,
    2999344380u, 3183782163u, 3723754342u, 759716128u,  3284107364u,
    1714496583u, 15918244u,   820509475u,  2553936299u, 2201876606u,
    4237151697u, 2605688266u, 3253705097u, 1008333207u, 712158730u,
    1722280252u, 1933868287u, 4152736859u, 2097020806u, 584426382u,
    2836501956u, 2522777566u, 1996172430u, 2122199776u, 1069285218u,
    1474209360u, 690831894u,  107482532u,  3695525410u, 670591796u,
    768977505u,  2412057331u, 3647886687u, 3110327607u, 1072658422u,
    379861934u,  1557579480u, 4124127129u, 2271365865u, 3880613089u,
    739218494u,  547346027u,  388559045u,  3147335977u, 176230425u,
    3094853730u, 2554321205u, 1495176194u, 4093461535u, 3521297827u,
    4108148413u, 1913727929u, 1177947623u, 1911655402u, 1053371241u,
    3265708874u, 1266515850u, 1045540427u, 3194420196u, 3717104621u,
    1144474110u, 1464392345u, 52070157u,   4144237690u, 3350490823u,
    4166253320u, 2747410691u,
};

bool test(uint8_t data[], int offset, int len = 0)
{
    using meta::hashing::farm_hash;
    using meta::hashing::farm_hash_seeded;
    using result_type = farm_hash::result_type;
    static int index = 0;

    auto check = [&](uint32_t actual)
    {
        uint32_t e = expected[index++];
        AssertThat(actual, Equals(e));
    };

    if (offset == -1)
    {
        int alive = 0;
        {
            farm_hash_seeded hasher{create_seed(offset, 0),
                                    create_seed(offset, 1)};
            hasher(data, static_cast<std::size_t>(len++));
            auto h = static_cast<result_type>(hasher);
            alive += (h >> 32) > 0;
            alive += ((h << 32) >> 32) > 0;
        }
        {
            farm_hash_seeded hasher{create_seed(offset, -1)};
            hasher(data, static_cast<std::size_t>(len++));
            auto h = static_cast<result_type>(hasher);
            alive += (h >> 32) > 0;
            alive += ((h << 32) >> 32) > 0;
        }
        {
            farm_hash hasher;
            hasher(data, static_cast<std::size_t>(len++));
            auto h = static_cast<result_type>(hasher);
            alive += (h >> 32) > 0;
            alive += ((h << 32) >> 32) > 0;
        }
        len -= 3;
        return alive > 0;
    }
    {
        farm_hash_seeded hasher{create_seed(offset, 0), create_seed(offset, 1)};
        hasher(data + offset, static_cast<std::size_t>(len));
        auto h = static_cast<result_type>(hasher);
        check(h >> 32);
        check((h << 32) >> 32);
    }
    {
        farm_hash_seeded hasher{create_seed(offset, -1)};
        hasher(data + offset, static_cast<std::size_t>(len));
        auto h = static_cast<result_type>(hasher);
        check(h >> 32);
        check((h << 32) >> 32);
    }
    {
        farm_hash hasher;
        hasher(data + offset, static_cast<std::size_t>(len));
        auto h = static_cast<result_type>(hasher);
        check(h >> 32);
        check((h << 32) >> 32);
    }

    return true;
}

void farm_hash_self_test()
{
    const static constexpr int data_size = 1 << 20;
    const static constexpr int test_size = 300;

    uint8_t data[data_size];

    // initialize data to pseudorandom values
    uint64_t a = 9;
    uint64_t b = 777;
    for (int i = 0; i < data_size; ++i)
    {
        a += b;
        b += a;
        a = (a ^ (a >> 41)) * meta::hashing::farm::k0;
        b = (b ^ (b >> 41)) * meta::hashing::farm::k0
            + static_cast<uint64_t>(i);
        data[i] = static_cast<uint8_t>(b >> 37);
    }

    AssertThat(test(data, -1), Equals(true));
    int i = 0;
    for (; i < test_size - 1; ++i)
        test(data, i * i, i);

    for (; i < data_size; i += i / 7)
        test(data, 0, i);

    test(data, 0, data_size);
}
}
